查看原文
其他

女朋友最近总是加班到深夜,为了揪出真相,我写出这个程序!

老鬼 程序员老鬼 2022-07-01

事情的起因:


今天不加班,开发小哥哥很早就回到家了,但是女朋友还没下班。
于是乎开发小哥哥就给女朋友发微信问为啥还没回家?

女朋友说她今晚上也要加班,可能要忙个通宵吧,

并且还发了一张美美的自拍给男朋友看。


敏感的开发小哥哥心生疑窦,心想:咋回事啊?哪有这么忙?这个月好几次了。

是不是有什么猫腻啊?

于是乎 自己用 python撸了一段代码来分析照片,就有了下面这些事。


结果显示女友照片的拍摄地址居然是在酒店,

卧槽 ,真的是离谱!

不希望其他兄弟们也被欺骗,小哥决定将代码倾情奉献,教程如下:


python分析照片

要将照片原图下载好,然后使用 Python 编写脚本。

通过该脚本能够读取照片拍摄的详细地址,

牛逼的是,地址能详细到了具体的街道和酒店名称!

引入exifread 模块

首先我们安装 python 的 exifread 模块,这个用于照片分析,

PS C:\WINDOWS\system32> pip install exifreadCollecting exifread Downloading ExifRead-2.3.2-py3-none-any.whl (38 kB)Installing collected packages: exifreadSuccessfully installed exifread-2.3.2PS C:\WINDOWS\system32> pip install json

GPS经纬度信息


鬼哥提醒大家发布在网上的照片,不要发原图,

这是因为在我们平时拍摄的照片里,隐藏了大量的私密信息,比如:拍摄时间和精确 GPS 信息

下面我们通过 exifread 模块读取照片内的经纬度信息。

#读取照片的GPS经纬度信息def find_GPS_image(pic_path): GPS = {} date = '' with open(pic_path, 'rb') as f: tags = exifread.process_file(f) for tag, value in tags.items(): #纬度 if re.match('GPS GPSLatitudeRef', tag): GPS['GPSLatitudeRef'] = str(value) #经度 elif re.match('GPS GPSLongitudeRef', tag): GPS['GPSLongitudeRef'] = str(value) #海拔 elif re.match('GPS GPSAltitudeRef', tag): GPS['GPSAltitudeRef'] = str(value) elif re.match('GPS GPSLatitude', tag): try: match_result = re.match('\[(\w*),(\w*),(\w.*)/(\w.*)\]', str(value)).groups() GPS['GPSLatitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2]) except: deg, min, sec = [x.replace(' ', '') for x in str(value)[1:-1].split(',')] GPS['GPSLatitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec) elif re.match('GPS GPSLongitude', tag): try: match_result = re.match('\[(\w*),(\w*),(\w.*)/(\w.*)\]', str(value)).groups() GPS['GPSLongitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2]) except: deg, min, sec = [x.replace(' ', '') for x in str(value)[1:-1].split(',')] GPS['GPSLongitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec) elif re.match('GPS GPSAltitude', tag): GPS['GPSAltitude'] = str(value) elif re.match('.*Date.*', tag): date = str(value) return {'GPS_information': GPS, 'date_information': date}

百度API将GPS转地址


读取到了 GPS 经纬度信息之后,我们要借助百度 API 将 GPS 经纬度信息转换为具体的地址信息。

我们需要一个调用百度API的 ak 值,

ak 值我们可以通过注册百度开发者获得或者你也可以使代码中的 ak 值。

调用之后,就可以将拍摄时间和拍摄详细地址解析出来。

def find_address_from_GPS(GPS): secret_key = 'zbLsuDDL4CS2U0M4KezOZZbGUY9iWtVf' if not GPS['GPS_information']: return '该照片无GPS信息' #经纬度信息 lat, lng = GPS['GPS_information']['GPSLatitude'], GPS['GPS_information']['GPSLongitude'] baidu_map_api = "http://api.map.baidu.com/geocoder/v2/?ak={0}&callback=renderReverse&location={1},{2}s&output=json&pois=0".format( secret_key, lat, lng) response = requests.get(baidu_map_api) #百度API转换成具体的地址 content = response.text.replace("renderReverse&&renderReverse(", "")[:-1] print(content) baidu_map_address = json.loads(content) #将返回的json信息解析整理出来 formatted_address = baidu_map_address["result"]["formatted_address"] province = baidu_map_address["result"]["addressComponent"]["province"] city = baidu_map_address["result"]["addressComponent"]["city"] district = baidu_map_address["result"]["addressComponent"]["district"] location = baidu_map_address["result"]["sematic_description"] return formatted_address,province,city,district,location if __name__ == '__main__': GPS_info = find_GPS_image(pic_path='C:/女友自拍.jpg') address = find_address_from_GPS(GPS=GPS_info) print("拍摄时间:" + GPS_info.get("date_information")) print('照片拍摄地址:' + str(address))


老王得到的结果是这样的


照片拍摄地址:云南省红河哈尼族彝族自治州弥勒县湖泉酒店-A座东南128米。

云南弥勒湖泉酒店,这就不是女友工作的地方,尼玛这是一家温泉度假酒店。

害~~

{"status":0,"result":{"location":{"lng":103.41424699999998,"lat":24.410461020097278},"formatted_address":"云南省红河哈尼族彝族自治州弥勒县","business":"","addressComponent":{"country":"中国","country_code":0,"country_code_iso":"CHN","country_code_iso2":"CN","province":"云南省","city":"红河哈尼族彝族自治州","city_level":2,"district":"弥勒县","town":"","town_code":"","adcode":"532526","street_number":"","direction":"","distance":""},"sematic_description":"湖泉酒店-A座东南128米","cityCode":107}} 拍摄时间:2021:5:03 20:05:32照片拍摄地址:('云南省红河哈尼族彝族自治州弥勒县', '云南省', '红河哈尼族彝族自治州', '弥勒县', '湖泉酒店-A座东南128米')

完整代码如下


import exifreadimport reimport jsonimport requestsimport os #转换经纬度格式def latitude_and_longitude_convert_to_decimal_system(*arg): """ 经纬度转为小数, param arg: :return: 十进制小数 """ return float(arg[0]) + ((float(arg[1]) + (float(arg[2].split('/')[0]) / float(arg[2].split('/')[-1]) / 60)) / 60) #读取照片的GPS经纬度信息def find_GPS_image(pic_path): GPS = {} date = '' with open(pic_path, 'rb') as f: tags = exifread.process_file(f) for tag, value in tags.items(): #纬度 if re.match('GPS GPSLatitudeRef', tag): GPS['GPSLatitudeRef'] = str(value) #经度 elif re.match('GPS GPSLongitudeRef', tag): GPS['GPSLongitudeRef'] = str(value) #海拔 elif re.match('GPS GPSAltitudeRef', tag): GPS['GPSAltitudeRef'] = str(value) elif re.match('GPS GPSLatitude', tag): try: match_result = re.match('\[(\w*),(\w*),(\w.*)/(\w.*)\]', str(value)).groups() GPS['GPSLatitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2]) except: deg, min, sec = [x.replace(' ', '') for x in str(value)[1:-1].split(',')] GPS['GPSLatitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec) elif re.match('GPS GPSLongitude', tag): try: match_result = re.match('\[(\w*),(\w*),(\w.*)/(\w.*)\]', str(value)).groups() GPS['GPSLongitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2]) except: deg, min, sec = [x.replace(' ', '') for x in str(value)[1:-1].split(',')] GPS['GPSLongitude'] = latitude_and_longitude_convert_to_decimal_system(deg, min, sec) elif re.match('GPS GPSAltitude', tag): GPS['GPSAltitude'] = str(value) elif re.match('.*Date.*', tag): date = str(value) return {'GPS_information': GPS, 'date_information': date} #通过baidu Map的API将GPS信息转换成地址。def find_address_from_GPS(GPS): """ 使用Geocoding API把经纬度坐标转换为结构化地址。 :param GPS: :return: """ secret_key = 'zbLsuDDL4CS2U0M4KezOZZbGUY9iWtVf' if not GPS['GPS_information']: return '该照片无GPS信息' lat, lng = GPS['GPS_information']['GPSLatitude'], GPS['GPS_information']['GPSLongitude'] baidu_map_api = "http://api.map.baidu.com/geocoder/v2/?ak={0}&callback=renderReverse&location={1},{2}s&output=json&pois=0".format( secret_key, lat, lng) response = requests.get(baidu_map_api) content = response.text.replace("renderReverse&&renderReverse(", "")[:-1] print(content) baidu_map_address = json.loads(content) formatted_address = baidu_map_address["result"]["formatted_address"] province = baidu_map_address["result"]["addressComponent"]["province"] city = baidu_map_address["result"]["addressComponent"]["city"] district = baidu_map_address["result"]["addressComponent"]["district"] location = baidu_map_address["result"]["sematic_description"] return formatted_address,province,city,district,locationif __name__ == '__main__': GPS_info = find_GPS_image(pic_path='C:/Users/pacer/desktop/img/5.jpg') address = find_address_from_GPS(GPS=GPS_info) print("拍摄时间:" + GPS_info.get("date_information")) print('照片拍摄地址:' + str(address))


往期推荐

阿里二面:请讲明白什么是分布式任务调度?

2021年05月编程语言、Web服务器和数据库排行榜,C 逐渐失去人气,Apache永远滴神!

我把 Spring Boot 项目从 18.18M 瘦身到 0.18M,部署起来真省事!

周末撸了一个简版的 Redis,轻松搞定高性能的 key-value 服务

面试官问:数据库连接池为什么要用threadlocal?不用会怎样?


耗时数月整理出来的技术书籍免费分享给大家
扫描下方二维码,回复关键字【电子书】获取!
喜欢的这里报道
↘↘↘

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存